// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.XPath;

using Microsoft.TeamFoundation.Migration.Toolkit.Linking;
using Microsoft.TeamFoundation.Migration.Toolkit.Wit;

namespace Microsoft.TeamFoundation.Migration.Toolkit
{
    /// <summary>
    /// Linking configuration.
    /// </summary>
    public class LinkingData
    {
        private string m_vcSession;                         // VC session name
        private string m_witSession;                        // WIT session name
        private ILinkEngine m_engine;                       // Linking engine
        private object m_lock = new object();               // Synchronization object
        private string m_provider;                          // Name of the linking engine provider
        private string m_engineData;                        // Engine's initialization data

        /// <summary>
        /// Returns name of the version control session.
        /// </summary>
        public string VersionControlSession { get { return m_vcSession; } internal set { m_vcSession = value; } }

        /// <summary>
        /// Returns name of the work item tracking session.
        /// </summary>
        public string WorkItemTrackingSession { get { return m_witSession; } internal set { m_witSession = value; } }

        /// <summary>
        /// Returns linking engine.
        /// </summary>
        public ILinkEngine Engine 
        { 
            get 
            {
                if (m_engine == null)
                {
                    lock (m_lock)
                    {
                        if (m_engine == null)
                        {
                            m_engine = MigrationConfiguration.Providers[m_provider].CreateInstance(
                                typeof(ILinkEngine), m_engineData) as ILinkEngine;
                            if (m_engine == null)
                            {
                                throw new InitializationException(
                                    MigrationToolkitResources.ErrorCreateLinkingEngine);
                            }

                            if (!string.IsNullOrEmpty(m_witSession))
                            {
                                m_engine.WorkItemTrackingSession = MigrationConfiguration.Current.Wit.Sessions[m_witSession];
                            }

                            if (!string.IsNullOrEmpty(m_vcSession))
                            {
                                m_engine.VersionControlSession = MigrationConfiguration.Current.VC.Sessions[m_vcSession];
                            }

                            // Release cached provider data (we needed it only for initialization)
                            m_provider = null;
                            m_engineData = null;
                        }
                    }
                }
                return m_engine; 
            } 
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="nav">Navigator positioned to the Linking section</param>
        internal LinkingData(
            XPathNavigator nav)
        {
            // Initialize the engine
            XPathNavigator e = nav.SelectSingleNode("Engine");
            m_provider = e.GetAttribute("provider", string.Empty);
            m_engineData = e.InnerXml;

            // Initialize sessions
            XPathNavigator session = nav.SelectSingleNode("VersionControl");
            if (session != null)
            {
                m_vcSession = session.GetAttribute("session", string.Empty);
            }
            session = nav.SelectSingleNode("WorkItemTracking");
            if (session != null)
            {
                m_witSession = session.GetAttribute("session", string.Empty);
            }
        }
    }
}
